package net.ewon.avatar.agent;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;

import net.ewon.avatar.common.exception.ServiceDependencyException;
import net.ewon.avatar.common.pkg.AvatarPackage;
import net.ewon.avatar.common.pkg.AvatarPackageFile;
import net.ewon.avatar.common.pkg.AvatarPackageSource;

import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.log4j.Logger;

@Consumes("application/json")
@Produces("application/json")
public class AvatarAgentService {

	private static final Logger logger = Logger
			.getLogger(AvatarAgentService.class);

	@Resource(name = "pkgMgmtServiceClient")
	private WebClient pkgServiceClient;

	@Resource(name = "avatarPackageRepo")
	private AvatarPackageRepo avatarPackageRepo;
	
	@Resource(name="runtimeEnv")
	private RuntimeEnvironment runtimeEnv;

	@POST
	@Path("/echo")
	public String echo(String hello) {
		System.out.println("Hello " + hello);
		return hello;
	}

	@GET
	@Path("/getName")
	public String getName() {
		return "guang";
	}

	@POST
	@Path("/missingAvatarPackages")
	public List<AvatarPackage> getMissingAvatarPackages(
			List<AvatarPackage> avatarPackages) {
		List<AvatarPackage> missingPackages = new ArrayList<AvatarPackage>();

		for (AvatarPackage avatarPackage : avatarPackages) {
			if (!avatarPackageRepo.exists(avatarPackage.getName(),
					avatarPackage.getVersion())) {
				missingPackages.add(avatarPackage);
			}
		}
		return missingPackages;
	}

	@POST
	@Path("/syncAvatarPackage")
	public String syncAvatarPackage(@QueryParam("pkgName") String pkgName,
			@QueryParam("version") String version,
			AvatarPackageSource avatarPackageSource)
			throws ServiceDependencyException {

		logger.info("Sync package with name: " + pkgName + ", version: "
				+ version + " from source " + avatarPackageSource.toString());

		pkgServiceClient.reset();
		pkgServiceClient.resetQuery();
		pkgServiceClient.path("AvatarPackageMgmtService/getAvatarPackage");
		pkgServiceClient.type("application/json").accept("application/json");
		pkgServiceClient.query("pkgName", pkgName);
		pkgServiceClient.query("version", version);

		AvatarPackage avatarPackage = pkgServiceClient.get(AvatarPackage.class);

		if (avatarPackage == null) {
			throw new ServiceDependencyException("Package " + pkgName
					+ " with version[" + version + "] doesn't exit in repo.");
		}

		List<AvatarPackageFile> avatarPackageFiles = new ArrayList<AvatarPackageFile>();

		pkgServiceClient.reset();
		pkgServiceClient.resetQuery();
		pkgServiceClient.type("application/json").accept("application/json");

		for (String fileId : avatarPackage.getFileIds()) {

			pkgServiceClient.reset();
			pkgServiceClient.resetQuery();
			pkgServiceClient.type("application/json")
					.accept("application/json");

			pkgServiceClient
					.path("AvatarPackageMgmtService/getAvatarPackageFile");

			pkgServiceClient.query("fileId", fileId);
			AvatarPackageFile pkgFile = pkgServiceClient
					.get(AvatarPackageFile.class);
			if (pkgFile == null) {
				throw new ServiceDependencyException("Package File with id "
						+ fileId + " doesn't exit in repo.");
			}
			avatarPackageFiles.add(pkgFile);
		}
		avatarPackageRepo.install(avatarPackageFiles);

		logger.info("Finished syncing package with name: " + pkgName + ", version: "
				+ version + " from source " + avatarPackageSource.toString());
		return "ok";
	}
	
	@POST
	@Path("/createLinks")
	public void createLinks(@QueryParam("envName") String envName,
			List<AvatarPackage> avatarPackages)
			throws ServiceDependencyException {
		try {
			runtimeEnv.deploy(envName, avatarPackages);
		} catch (IOException e) {
			logger.error("Failed to create link for env "+ envName);
			throw new ServiceDependencyException("Failed to create link for env "+ envName, e);
		}
	}
	
 
}
